package UsedCar;

import java.util.ArrayList;

import org.apache.commons.lang.StringUtils;

import uchicago.src.sim.util.Random;

public final class Knowledges {

	/**
	 * @param carTypes
	 *            知識類型
	 * @param knowNum
	 *            知識總量
	 * @param proRatio
	 *            專業知識的比例
	 * @param knows
	 *            知識
	 * 
	 */
	protected int carTypes, knowNum;
	protected float proRatio;
	protected String[] knows;

	/**
	 * 建構子
	 * 
	 * @param ct
	 *            汽車種類
	 * @param proRatio
	 *            專業知識比例
	 * @param knowmax
	 *            知識最大數目
	 */
	public Knowledges(int ct, float proRatio, int knowmax) {
		// 產生亂數種子
		long s = System.currentTimeMillis();
		Random.setSeed(s);

		this.carTypes = ct;
		this.proRatio = proRatio;
		this.knowNum = knowmax;

		initKnows();
	}

	/**
	 * 在 haystack 中找看看是否有 needle 的存在
	 * 
	 * @param haystack
	 *            被找的知識串
	 * @param needle
	 *            某個知識
	 * @return 真假
	 */
	public boolean in_array(String[] haystack, String needle) {
		for (int i = 0; i < haystack.length; i++) {
			if (haystack[i].equals(needle)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 產生世界裡的所有知識
	 */
	public void initKnows() {
		ArrayList<String> rKnows = new ArrayList<String>();

		int basicNum = (int) (this.knowNum * (1 - this.proRatio));

		for (int j = 0; j < this.carTypes; j++) {
			for (int i = 0; i < basicNum; i++) {
				rKnows.add("T" + j + "_B" + i);
			}
			for (int i = basicNum; i < basicNum
					+ (int) (this.proRatio * this.knowNum); i++) {
				rKnows.add("T" + j + "_P" + i);
			}
		}

		this.knows = (String[]) rKnows.toArray(new String[rKnows.size()]);
	}

	/**
	 * @param knowR
	 *            知識比例
	 * @return String[] 產生的隨機知識
	 */
	public String[] getRoleKnows(float knowR) {
		ArrayList<String> reKnow = new ArrayList<String>();

		// if this agent is a seller

		for (int j = 0; j < this.knows.length; j++) {

			boolean choose;

			if (knowR > 0.9) {
				choose = true;
			} else {
				Random.createUniform();
				choose = (Random.uniform.nextIntFromTo(1, this.knows.length) < this.knows.length
						* knowR);
			}
			if (choose) {
				reKnow.add(this.knows[j]);
			}
		}

		String[] rknows = (String[]) reKnow.toArray(new String[reKnow.size()]);

		return rknows;
	}

	/**
	 * 列出世界裡的所有知識
	 */
	public void listInitKnows() {
		String foobar = this.listKnows(this.knows);

		System.out.println(foobar);
	}

	/**
	 * 取得知識串中的任何知識
	 * 
	 * @param frmKnows
	 *            知識來源
	 * @param knowsR
	 *            知識比例
	 * @return 知識串
	 */
	public String[] getKnows(String[] frmKnows, float knowsR) {
		ArrayList<String> reKnow = new ArrayList<String>();

		for (int i = 0; i < frmKnows.length; i++) {
			boolean choose = (Random.uniform.nextIntFromTo(0, frmKnows.length) < frmKnows.length
					* knowsR);

			if (choose) {
				reKnow.add(frmKnows[i]);
			}
		}
		String[] rknows = (String[]) reKnow.toArray(new String[reKnow.size()]);

		return rknows;
	}

	/**
	 * 取得知識串中的基本知識
	 * 
	 * @param frmKnows
	 *            知識來源
	 * @param knowsR
	 *            知識比例
	 * @return 知識串
	 */
	public String[] getKnowsBasic(String[] frmKnows, float knowsR) {
		ArrayList<String> reKnow = new ArrayList<String>();

		for (int i = 0; i < frmKnows.length * this.proRatio; i++) {
			boolean choose = (Random.uniform.nextIntFromTo(0,
					(int) (frmKnows.length * this.proRatio)) < frmKnows.length
					* knowsR);

			if (choose && frmKnows[i].matches("T._B.")) {
				reKnow.add(frmKnows[i]);
			}
		}
		String[] rknows = (String[]) reKnow.toArray(new String[reKnow.size()]);

		return rknows;
	}

	/**
	 * 依車型取得隨機知識
	 * 
	 * @param maxNum
	 *            知識最大值
	 * @param type
	 *            車型
	 * @return 知識串
	 */
	public String[] getRandKnowsEachType(int maxNum, int type) {
		ArrayList<String> reKnow = new ArrayList<String>();

		for (int i = 0; i < this.knowNum; i++) {
			Random.createUniform();
			boolean choose = (Random.uniform.nextIntFromTo(0, this.knowNum) < maxNum);
			if (choose) {
				if (i >= (this.knowNum * (1 - this.proRatio))) {
					reKnow.add("T" + type + "_P" + i);
				} else {
					reKnow.add("T" + type + "_B" + i);
				}

			}
		}

		String[] rknows = (String[]) reKnow.toArray(new String[reKnow.size()]);

		return rknows;
	}

	/**
	 * 例出知識字串，品質串
	 * 
	 * @param knows
	 *            知識
	 * @return 知識字串
	 */
	public String listKnows(String[] knows) {
		return StringUtils.join(knows, ", ");
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// Knowledges foo = new Knowledges(2, (float) 0.3, 10);

	}

	// ---------------------------------------------------------------------------------------------------------------------------------------------//
	// 變數的 setter and getter
	// ---------------------------------------------------------------------------------------------------------------------------------------------//
	public int getCarTypes() {
		return carTypes;
	}

	public void setCarTypes(int carTypes) {
		this.carTypes = carTypes;
	}

}
